package com.sz.biz.logistics.ord.service.impl;

import com.sz.biz.common.constants.ModuleNames;
import com.sz.biz.common.utils.TrimString;
import com.sz.biz.logistics.constants.OrderNumberConstants.*;
import com.sz.biz.logistics.ord.entity.OrdWaybillPrearrange;
import com.sz.biz.logistics.ord.enums.OrdServiceTypeEnum;
import com.sz.biz.logistics.ord.service.OrdWaybillNoManagementService;
import com.sz.biz.logistics.ord.service.OrdWaybillNoPrearrangeService;
import com.sz.common.base.constants.UserActions;
import com.sz.common.base.dao.ParamData;
import com.sz.common.base.service.AbstractService;
import com.sz.common.base.utils.CollectionUtils;
import com.sz.common.base.utils.StringUtils;
import com.sz.common.core.service.PrincipalLogUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Package: com.sz.biz.logistics.ord.service.impl<br>
 * Description: TODO: ADD FUNCTION<br>
 * @author WuHan<br>
 * Date: 2017-10-12 18:35<br>
 * @since ${TAG}
 */
@Service("OrdWaybillNoPrearrangeService")
public class OrdWaybillNoPrearrangeServiceImpl
        extends AbstractService
        implements OrdWaybillNoPrearrangeService {
    
    private OrdWaybillNoManagementService ordWaybillNoManagementService;
    
    @Autowired
    private OrdWaybillNoPrearrangeServiceImpl(OrdWaybillNoManagementService ordWaybillNoManagementService){
        this.ordWaybillNoManagementService = ordWaybillNoManagementService;
    }
    
    /**
     * 批量分配号段。
     * @param ordServiceTypeEnum 业务类型
     * @param amount 号码数
     * @param startIndex 起始号码
     * @return 影响行数
     * */
    @Override
    public int batchAllocate(OrdServiceTypeEnum ordServiceTypeEnum, int amount, String startIndex, String refId) {
        int res = 0;
        String serviceType = ordServiceTypeEnum.getType();
        if (!StringUtils.isEmpty(serviceType) && !StringUtils.isEmpty(startIndex) && !StringUtils.isEmpty(refId)) {
            if (startIndex.matches(RuleRegex.WAYBILLNUMBER_REGEX) && serviceType.matches(RuleRegex.SERVICETYPE_REGEX)) {
                String endIndex = String.valueOf(Long.parseLong(startIndex) + amount - 1);
                startIndex = TrimString.fillStringLengthByZero(startIndex, 8);
                endIndex = TrimString.fillStringLengthByZero(endIndex, 8);
                try {
                    if (ordWaybillNoManagementService.collisionDetect(serviceType, startIndex, endIndex)) {
                        ParamData pd = new ParamData();
                        if (!StringUtils.isEmpty(startIndex) && amount > 0) {
                            pd.put("serviceType", serviceType);
                            pd.put("startIndex", startIndex);
                            pd.put("endIndex", endIndex);
                            pd.put("refId", refId);
                        }
                        res = dao.save(getSqlName("prearrangeNumbers"), pd);
                        //保存操作日志
                        Map<String, Object> dataBackup = new HashMap<>(1);
                        dataBackup.put("ADD_PREARRANGED_WAYBILL_NUMBERS", pd);
                        PrincipalLogUtils.addOperationLog(ModuleNames.ORD, ModuleNames.ORD_WAYBILLNO, UserActions.ADD, "添加订单编号预分配号段", dataBackup);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return res;
    }
    
    /**
     * 获取各类运单当前最近的预分配号段起始值。
     * @param currentSerialNumbers 包含三类业务类型最大单号的集合。
     * @return 三类业务各自最近的预分配号段起始值。
     * */
    @Override
    public List<String> fetchNearestMargins(List<String> currentSerialNumbers) {
        ParamData pd = new ParamData();
        if (!CollectionUtils.isEmpty(currentSerialNumbers)) {
            pd.put(WaybillNumber.LOGISTIC_HEAD_NUMBER, StringUtils.isEmpty(currentSerialNumbers.get(0)) ? WaybillNumber.DEFAULT_NUMBER : currentSerialNumbers.get(0));
            pd.put(WaybillNumber.TRADING_HEAD_NUMBER, StringUtils.isEmpty(currentSerialNumbers.get(0)) ? WaybillNumber.DEFAULT_NUMBER : currentSerialNumbers.get(1));
            pd.put(WaybillNumber.FINANCE_HEAD_NUMBER, StringUtils.isEmpty(currentSerialNumbers.get(0)) ? WaybillNumber.DEFAULT_NUMBER : currentSerialNumbers.get(2));
        }
        return dao.findForList(getSqlName("fetchNearestMargins"), pd, String.class);
    }
    
    /**
     * 获取各类运单当前最近可用号段起始值。
     * @param currentSerialNumbers 包含三类业务类型最大单号的集合。
     * @return 三类业务各自最近的可用号段起始值。
     * */
    @Override
    public List<String> fetchAvailableNumbers(List<String> currentSerialNumbers) {
        List<String> res = new ArrayList<>();
        if (!CollectionUtils.isEmpty(currentSerialNumbers)) {
            for (int i = 0; i < currentSerialNumbers.size(); i++) {
                ParamData pd = new ParamData();
                pd.put("currentSerialNumber", StringUtils.isEmpty(currentSerialNumbers.get(i)) ? WaybillNumber.DEFAULT_NUMBER : currentSerialNumbers.get(i));
                pd.put("serviceType", i + 1);
                List<OrdWaybillPrearrange> list = dao.findForList(getSqlName("fetchAllocatedBlocks"), pd, OrdWaybillPrearrange.class);
                if (list.size() == 1) {
                    if (Long.valueOf(list.get(0).getEndNumber()) < 99999999) {
                        res.add(String.valueOf(Long.valueOf(list.get(0).getEndNumber()) + 1));
                    } else {
                        res.add(WaybillNumber.DEFAULT_NUMBER);
                    }
                } else if (list.size() > 1) {
                    int j = 0;
                    while (j < list.size() - 1) {
                        if (Long.valueOf(list.get(j + 1).getStartNumber())
                                - Long.valueOf(list.get(j).getEndNumber()) > 1) {
                            res.add(String.valueOf(Long.valueOf(list.get(j).getEndNumber()) + 1));
                            break;
                        } else {
                            j++;
                        }
                    }
                    if (j == list.size() - 1) {
                        if (Long.valueOf(list.get(j).getEndNumber()) < 99999999) {
                            res.add(String.valueOf(Long.valueOf(list.get(j).getEndNumber()) + 1));
                        } else {
                            res.add(WaybillNumber.DEFAULT_NUMBER);
                        }
                    }
                } else if (CollectionUtils.isEmpty(list)) {
                    res.add(WaybillNumber.DEFAULT_NUMBER);
                }
            }
        }
        return res;
    }
    
    @Override
    public List<OrdWaybillPrearrange> fetchBlockList(String serviceType, @Nullable String userId) {
        ParamData pd = new ParamData();
        if (!StringUtils.isEmpty(serviceType) && serviceType.matches(RuleRegex.SERVICETYPE_REGEX)) {
            pd.put("serviceType", serviceType);
            if (!StringUtils.isEmpty(userId) && !userId.matches(RuleRegex.PURE_NUMBER)) {
                throw new IllegalArgumentException("传入用户ID不正确！");
            } else {
                pd.put("refId", userId);
            }
        } else {
            throw new IllegalArgumentException("传入业务类型不正确或内容为空！");
        }
        return dao.findForList(getSqlName("fetchBlockList"), pd, OrdWaybillPrearrange.class);
    }
}
